﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;

namespace arb.SharePoint.SecureSilverlight
{
    public class Builders
    {
        #region List And Instance Builders
        public static List<WebPartInstance> GetWebPartInstanceList()
        {
            SPList instanceList = GetInstanceList();
            return (instanceList.Items.Cast<SPListItem>().Select(item => new WebPartInstance
             {
                 RootWebTitle = item.GetSafeValue<string>(Constants.RootWebTitleField),
                 PageTitle = item.GetSafeValue<string>(Constants.PageTitleField),
                 PageUrl = item.GetFieldValueUrl(Constants.PageUrlField),
                 SilverlightFileBeingUsed = item.GetSafeValue<string>(Constants.SilverlightFileField),
                 LastModifiedDate = item.GetSafeValueNulled<DateTime>(Constants.LastModifiedDateField),
             })).ToList();
        }

        public static SPList GetInstanceList()
        {
            SPList elevatedList = null;
            SPSecurity.RunWithElevatedPrivileges(delegate
                                                     {
                                                         SPWeb web = SPContext.Current.Site.RootWeb;
                                                         elevatedList = web.Lists[Constants.InstanceListName];
                                                     });
            return elevatedList;
        }



        public static bool DoesInstanceExist(WebPartInstance instance)
        {
            List<WebPartInstance> instancesPrepped = GetWebPartInstanceList();
            return instancesPrepped.Where
                       (x => String.Equals(x.PageTitle, instance.PageTitle, StringComparison.InvariantCultureIgnoreCase) &&
                             String.Equals(x.PageUrl, instance.PageUrl, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault() != null;

        }

        public static SPContentType CreateContentTypeForInstanceList(SPWeb web)
        {
            SPContentType customContentType = new SPContentType(web.AvailableContentTypes["ParentContentType"],
                                                                web.ContentTypes, Constants.InstanceContentType);
            web.Fields.Add(Constants.RootWebTitleField, SPFieldType.Text, true);
            SPFieldLink webTitle = new SPFieldLink(web.Fields[Constants.RootWebTitleField]);

            customContentType.FieldLinks.Add(webTitle);

            web.Fields.Add(Constants.PageTitleField, SPFieldType.Text, true);
            SPFieldLink pageTitle = new SPFieldLink(web.Fields[Constants.PageTitleField]);
            customContentType.FieldLinks.Add(pageTitle);

            web.Fields.Add(Constants.PageUrlField, SPFieldType.Text, true);
            SPFieldLink pageUrl = new SPFieldLink(web.Fields[Constants.PageUrlField]);
            customContentType.FieldLinks.Add(pageUrl);

            web.Fields.Add(Constants.SilverlightFileField, SPFieldType.Text, true);
            SPFieldLink slFile = new SPFieldLink(web.Fields[Constants.SilverlightFileField]);
            customContentType.FieldLinks.Add(slFile);

            web.Fields.Add(Constants.LastModifiedDateField, SPFieldType.Text, true);
            SPFieldLink modifiedDate = new SPFieldLink(web.Fields[Constants.LastModifiedDateField]);
            customContentType.FieldLinks.Add(modifiedDate);

            if (!web.ContentTypeExists(Constants.InstanceContentType))
            {
                web.ContentTypes.Add(customContentType);
                customContentType.Update();
                customContentType.AddGroupCheckEvent(".HandleGroupCheckEvent");
            }

            return customContentType;
        }

        #endregion

        #region General Builders
        public static void ChangeOrInsertAndAppendParams(bool doesexist, WebPartInstance obj)
        {
            SilverlightWebPartHost.Parameters += String.Format("UserName={0}", SPContext.Current.Web.CurrentUser);
            if (doesexist)
            {
                SPRoleDefinitionBindingCollection permCollection = null;
                var collection = new CommaDelimitedStringCollection();
                foreach (SPListItem item in GetInstanceList().Items.Cast<SPListItem>().Where
                    (item => (String.Equals(item.GetSafeValue<string>(Constants.PageTitleField), obj.PageTitle, StringComparison.InvariantCultureIgnoreCase) &&
                     (String.Equals(item.GetFieldValueUrl(Constants.PageUrlField), obj.PageUrl, StringComparison.InvariantCultureIgnoreCase)))))
                {
                    item.ParentList.ParentWeb.AllowUnsafeUpdates = true;
                    item[Constants.LastModifiedDateField] = DateTime.Now;
                    item[Constants.SilverlightFileField] = obj.SilverlightFileBeingUsed;
                    item.Update();
                    item.ParentList.ParentWeb.AllowUnsafeUpdates = false;
                    permCollection = item.AllRolesForCurrentUser;
                }
                if (permCollection != null)
                {
                    foreach (SPRoleDefinition def in permCollection)
                    {
                        collection.Add(def.Name);
                    }
                    if (collection.Count != 0)
                    {
                        SilverlightWebPartHost.Parameters += String.Format(",Roles={0}", collection.ToString().Replace(",", ";"));
                    }
                }
            }
            else
            {
                SPListItem newItem = GetInstanceList().Items.Add();
                newItem.ParentList.ParentWeb.AllowUnsafeUpdates = true;
                newItem[Constants.TitleField] = obj.RootWebTitle;
                newItem[Constants.PageTitleField] = obj.PageTitle;
                newItem[Constants.SilverlightFileField] = obj.SilverlightFileBeingUsed;
                newItem[Constants.PageUrlField] = obj.PageUrl;
                newItem[Constants.LastModifiedDateField] = obj.LastModifiedDate;
                newItem.Update();
                newItem.ParentList.ParentWeb.AllowUnsafeUpdates = true;

                if (!String.IsNullOrEmpty(SilverlightWebPartHost._emailAddress))
                {
                    SPUtility.SendEmail(SPContext.Current.Web, true, true,
                                        SilverlightWebPartHost._emailAddress,
                                        "Silverlight File Has Been Added - Security Config Required",
                                        String.Format("A New Silverlight Invocation Has Been detected at: <{0}><{1}><{2}>", obj.RootWebTitle, obj.PageUrl, obj.SilverlightFileBeingUsed));
                }
            }
        }

        public static Table GenerateToolPartHeader()
        {
            Table table = new Table();
            TableRow rowAppName = new TableRow();
            TableRow rowAuthor = new TableRow();
            TableRow rowSiteLink = new TableRow();
            TableCell appNameCell = new TableCell { HorizontalAlign = HorizontalAlign.Center };
            TableCell authorNameCell = new TableCell { HorizontalAlign = HorizontalAlign.Center };
            TableCell siteLinkCell = new TableCell { HorizontalAlign = HorizontalAlign.Center };
            rowAppName.Cells.Add(appNameCell);
            rowAuthor.Cells.Add(authorNameCell);
            rowSiteLink.Cells.Add(siteLinkCell);
            table.Rows.Add(rowAppName);
            table.Rows.Add(rowAuthor);
            table.Rows.Add(rowSiteLink);

            Label lblAppName = new Label { Text = Constants.ApplicationName };
            appNameCell.Controls.Add(lblAppName);

            Label lblAuthorName = new Label { Text = Constants.AuthorName };
            authorNameCell.Controls.Add(lblAuthorName);

            LinkButton linkToArb = new LinkButton { Text = Constants.WebSiteLink, PostBackUrl = Constants.WebSiteLink };
            siteLinkCell.Controls.Add(linkToArb);
            return table;
        }

        public static bool IsValidEmail(string inputEmail)
        {
            const string strRegex = @"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}" +
                                    @"\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\" +
                                    @".)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";
            var re = new Regex(strRegex);
            return re.IsMatch(inputEmail);
        }
        #endregion

        #region Security Builders

        public static SPGroup GetGroupOrCreate(SPWeb web, string name, string description, SPUser owner, SPUser defaultUser, bool associate)
        {
            return web.GetOrCreateGroup(name,
                (builderWeb, builderName) =>
                {
                    var builderGroups = builderWeb.SiteGroups;
                    builderGroups.Add(builderName, owner, defaultUser, description);
                    return builderGroups[name];
                },
                (assocWeb, assocGroup) =>
                {
                    if (associate && !assocWeb.AssociatedGroups.Contains(assocGroup))
                    {
                        web.AssociatedGroups.Add(assocGroup);
                        web.Update();
                    }
                });
        } 
        #endregion
    }
}
